{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a82bc933-3ff2-4f49-ad2b-b98590b80bb1",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = \"all\"\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "#warnings.filterwarnings(action, message='', category=Warning, module='', lineno=0, append=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b24d8704-f6a8-4024-acbd-ba7dd893b109",
   "metadata": {},
   "source": [
    "## 3.Packages and Builtin Functions\n",
    "\n",
    "- dir(): This function takes in an object and returns the _dir_() of that object giving us the attributes of the object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "47eb76e9-86ac-4da9-b574-19e3fd64d335",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "name = 'Rob'\n",
    "dir(name)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b03b05d6-49ba-4ee6-acef-7936781ab918",
   "metadata": {},
   "source": [
    "This code demonstrates that in Python, when you use the `dir()` function on a string object, it returns a list of all the attributes and methods of that object. `dir()` is a very useful built-in function for exploring an object's capabilities, or in other words, to see what attributes and methods are available for use on that object.\n",
    "  In the example you provided, `name` is a string object with the value 'Rob'. When you call `dir(name)`, you get a list that contains all the methods of the string object, such as `upper()` for converting the string to uppercase, `lower()` for converting the string to lowercase, and `split()` for splitting the string into substrings, among others.\n",
    "  Most of these methods are standard for operating on strings, while those with double underscores before and after their names, such as `__add__` and `__len__`, are Python's magic methods (also known as special methods). These methods typically serve special functions; for example, the `__add__` method implements the addition operator `+`, allowing you to concatenate two strings using `+`.\n",
    "  This list is very useful for understanding what can be done with Python strings, and it also shows the dynamic nature and flexibility of the Python language. With these methods, you can easily manipulate and work with text data."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a587b0c-2d8d-4415-a1aa-cd53abe68666",
   "metadata": {},
   "source": [
    "## 4.Data Types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "778b2fa2-44a7-4b2e-876a-c1c92b394694",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "'''<class \"str\">\n",
    "<class \"int\">\n",
    "<class \"float\">\n",
    "+\n",
    "-\n",
    "*\n",
    "/'''"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e1b5f1c-c112-4a8d-bff8-8f2518b957e8",
   "metadata": {},
   "source": [
    "- real and imaginary parts of complex numbers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "78a93bc0-d8dc-40f8-944d-c522727b68db",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = 3+5j\n",
    "y = 5j\n",
    "x.real\n",
    "x.imag"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a838e10d-80ac-4e48-afb6-1a1bd4c11ffa",
   "metadata": {},
   "source": [
    "- Integers or floats can be converted into a boolean using the built-in function bool. This treats any value as 0 or 0.0 as False and any other value to be True."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "380f0f27-d90d-41d9-959c-c4edf6dfb9d7",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x\n",
    "y = bool(0.0)\n",
    "y\n",
    "z = bool(-10)\n",
    "z"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd9fd069-0a31-438f-a322-c2d47dd4b25b",
   "metadata": {},
   "source": [
    "- Surprisingly we can use the operators in this chapter on boolean variables. The key to note is that a value of True is evaluated as 1 and False as 0, so you can see examples of this below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "37c0958d-9719-457e-b646-f669de99b724",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = True \n",
    "y = False\n",
    "x + y\n",
    "x - y\n",
    "x * y\n",
    "x / y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bdc683cf-09bf-46e3-a4fa-87cadd744b20",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = True \n",
    "y = True\n",
    "x + y\n",
    "x - y\n",
    "x * y\n",
    "x / y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0e97fbaf-40f7-467d-80e2-b6dd887fd89f",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = False\n",
    "y = False\n",
    "x + y\n",
    "x - y\n",
    "x * y\n",
    "x / y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4434bfef-73b2-4740-ad48-ea03099a5e12",
   "metadata": {},
   "source": [
    "- create byte, byte arrays and memory view objects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0e892d94-82b6-4943-83e4-426379be11ae",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = b\"Hello World\"\n",
    "x\n",
    "\n",
    "y = bytearray(6)\n",
    "y\n",
    "\n",
    "z = memoryview(bytes(5))\n",
    "z"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a074fdfc-cf7b-48a8-88c4-5095eb69289a",
   "metadata": {},
   "source": [
    "## 5.Operators"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d9bf730-bfcd-4a07-b6f3-508e31dbc32c",
   "metadata": {},
   "source": [
    "- define a variable, assigning the variable\n",
    "\n",
    "- It is a very subtle difference so you need to be careful with it. A simpler explanation is that == returns True if the variables being compared are equal, whereas is checks whether they are the same."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "328963d8-2ec8-4ce2-b0cb-f6fe916969d2",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "a = 1 \n",
    "a is 1 \n",
    "\n",
    "a == 1 \n",
    "\n",
    "a = [] \n",
    "b = [] \n",
    "a is b \n",
    "\n",
    "a == b "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85ba286e-2dae-4c13-81c6-e2284fd07446",
   "metadata": {},
   "source": [
    "However, they are both lists so using the comparison statement == we return True as they are both empty lists. If we assigned a as a list and b = a we would get the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0cf6e9c9-dd46-4115-a1e2-9166e78543c3",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "a = [] \n",
    "b = a \n",
    "a is b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d26f7ba4-efa9-4792-819c-1ecb9539dad7",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x/y #division\n",
    "x//y #floor division\n",
    "x%y #modulus\n",
    "x**y #exponentiation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6049089f-5a00-44a4-b294-66159476c971",
   "metadata": {
    "tags": []
   },
   "source": [
    "## 6.**Dates**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16d698db-337c-435e-b10f-08c27f01ecca",
   "metadata": {},
   "source": [
    "- datetime()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "098474c8-73bc-4ce5-ba56-956da54c1654",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "from datetime import timedelta\n",
    "from datetime import date\n",
    "d1 = datetime(2017, 5, 16, 10, 0, 11)\n",
    "change = timedelta(days=1, hours=2, minutes=10)\n",
    "d2 = date.today()\n",
    "d3 = datetime.now()\n",
    "d1\n",
    "d2\n",
    "d3\n",
    "change"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0bc82a8b-1c37-4ec6-adc3-9cc0477d75ed",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import datetime as dt\n",
    "now_date = dt.datetime.now()\n",
    "now_date"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a748aeca-63a3-47c4-a209-b0149d285fbb",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "moon_date = dt.datetime(1969, 7, 20)\n",
    "moon_date"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7ab5fa9-d45d-416e-8faf-13d6df929873",
   "metadata": {},
   "source": [
    "**notice1**\n",
    "\n",
    "The statement `datetime.now()` directly calls the `now()` class method of the `datetime` class within the `datetime` module. The key point is that the `datetime` module and the `datetime` class have the same name, which can cause some confusion. However, when you import the `datetime` module directly, Python is able to distinguish between the module and the class because you use the fully qualified name `datetime.datetime` when calling the class method.\n",
    "\n",
    "`datetime.now()` is a convenience function within the `datetime` module, which is actually a shorthand for `datetime.datetime.now()`, the latter being a class method of the `datetime` class. When you import the `datetime` module directly, the Python interpreter handles this situation automatically, allowing you to use `datetime.now()` directly.\n",
    "\n",
    "Therefore, you only need to use `dt.datetime.now()` to get the current date and time when you use an import statement like `import datetime as dt`. This is because you have renamed the `datetime` module to `dt`, so you need to use `dt` to access the `datetime` class within the module.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29af8c54-6bd3-488c-9c5a-c8a7904601a4",
   "metadata": {},
   "source": [
    "**notice2**\n",
    "\n",
    "`datetime` and `date`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "613d4035-ecb7-4b33-a8c6-4476cc2f0b50",
   "metadata": {},
   "source": [
    "other usages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d7fcaa0-ae48-4cb5-b04b-1fda1cee2b79",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "d1 = datetime(2017, 5, 17, 12, 10, 11)\n",
    "d2 = datetime(2016, 4, 7, 1, 1, 1)\n",
    "d1-d2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d37435d4-df01-4592-bde6-09281e00c7e0",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "date_since_moon = now_date - moon_date\n",
    "date_since_moon"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fbc20c00-5711-4d62-9867-0ebf1af50b2e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "date_since_moon.days"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e53875e0-f9cc-4b12-8c63-f5a4939a13d9",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "date_since_moon.seconds"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f751109-05eb-4f0a-ab95-6b599d28021d",
   "metadata": {},
   "source": [
    "## 7.Lists"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99542ed7-d6b3-492c-a76b-a8b7b6c09e2b",
   "metadata": {},
   "source": [
    "- pop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33fc400d-e7e3-4446-bf59-25b906f0039e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "stuff=[0,2,6,4] #example\n",
    "stuff\n",
    "stuff.pop() #removes the last item of the list \n",
    "stuff"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15c46c9d-562b-4091-9334-ef90b71cbf99",
   "metadata": {},
   "source": [
    "- append"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f9beaba8-5123-44e6-8b3d-59437c90d89b",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "stuff.append(9) #add an element to the end of the list\n",
    "stuff"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d45e2397-8749-4671-8642-edaecf01363d",
   "metadata": {},
   "source": [
    "- remove"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a4d00bda-4c88-4c79-a0b9-188e898b46b7",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "stuff.remove(9) # by using the attribute remove,remove 9 from the list,specify the name of the item we wanted to remove\n",
    "stuff"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "837ea7d6-3c76-475b-b4b9-22656a083660",
   "metadata": {},
   "source": [
    "- count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bead09f0-1ef1-4efe-8155-697654dae231",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "count_list = [1,1,1,2,3,4,4,5,6,9,9,9] #get the count of in the list\n",
    "count_list\n",
    "count_list.count(1)\n",
    "count_list.count(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d930b94d-7cad-4521-8c93-a8c3292cdb98",
   "metadata": {},
   "source": [
    "- reverse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82b2f555-ba46-4c09-afcd-6637350d8aa0",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "count_list.reverse() #reverses the elements in a list\n",
    "count_list"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4c99762-239f-4f29-8e34-2886bad556d4",
   "metadata": {},
   "source": [
    "- sort"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c512b42b-b203-4410-b035-6a0f6224a052",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "count_list.sort() #we can only use the sort method on a list of numeric values\n",
    "count_list"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "95201e04-3bee-4e68-af37-d0c577cedd56",
   "metadata": {},
   "source": [
    "- len"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "43c2ee41-5461-4def-a3a5-feef5561f9af",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "len(stuff) #get the length of the list"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "975f9810-dd0e-4840-a5df-35c0cf367d7f",
   "metadata": {},
   "source": [
    "- used negative indexing to choose item in a list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "62bc7a47-bc54-4507-a71c-7459b576dbe5",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "stuff[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3712c9ec-c08d-470a-a27c-cefc6f58980d",
   "metadata": {},
   "source": [
    "- choose element"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b750c268-6524-44be-8acc-569c58ee1371",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "stuff=[0,2,6,4] #example\n",
    "stuff[1:3] #take from the element in index 1 in the list and show up to but not including element in index 3 in the list\n",
    "stuff[1:] #select everything except the first element\n",
    "stuff #select everything,shows the full list\n",
    "\n",
    "stuff=[0,2,6,4] #example\n",
    "new_stuff = stuff[-1:]\n",
    "new_stuff\n",
    "new_stuff = stuff[:-1]\n",
    "new_stuff\n",
    "stuff[1:8:2]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e89982f7-9049-48b7-a6dc-14f52c55d468",
   "metadata": {},
   "source": [
    "- boolean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5876d64a-dd5c-46ec-9c5f-12d023426a88",
   "metadata": {},
   "outputs": [],
   "source": [
    "stuff=[0,2,6,4] #example\n",
    "9 in stuff #If the value is in we get back a boolean value True or False."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f6eada3-58fa-493b-99e9-fe6656010f93",
   "metadata": {},
   "source": [
    "- copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dafb08d4-ee2e-4a56-9fc3-dfd510582de2",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "new_stuff = stuff.copy() #take a copy of the list"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fc28b6f-850a-46aa-9caa-b548b40eb522",
   "metadata": {},
   "source": [
    "- clear"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "62dc1b4d-0eab-4207-81af-fa28f92f93bf",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "stuff.clear() #simply put this method clears the list of all its content\n",
    "stuff"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdb6f852-415c-4932-9bfd-a0bcaf7a9cad",
   "metadata": {},
   "source": [
    "- select"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25999e2b-e607-47d1-8323-98fa7cbd81a0",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = range(1,7,2)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35d28236-45b8-4847-aeb4-7d1f391deb9c",
   "metadata": {},
   "source": [
    "- obtain the start, stop and step of the range object alongside the count and index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dbae1704-e1f3-461c-98d6-017cbe3e0932",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = range(7)\n",
    "x\n",
    "x = x[1:]\n",
    "x\n",
    "\n",
    "x.start\n",
    "x.stop\n",
    "x.step\n",
    "x.index(1)\n",
    "x.count(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d786aff6-c139-4d18-b4d1-f86596861320",
   "metadata": {},
   "source": [
    "## 8.**Tuples**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ba9a870-29d4-42f5-b09e-c50275c38c50",
   "metadata": {},
   "source": [
    "You access them in exactly the same way and many things we covered in lists are relevant to tuples, the big difference is tuples can’t be modified."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35e98e2a-3a9a-4231-a4c6-c631927b33ce",
   "metadata": {},
   "source": [
    "- create"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c039cec-f25d-4a9f-bb93-d71164c27aac",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "numbers = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\n",
    "numbers"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08e460b5-4b85-450d-a3b0-6a62f6e2c9e9",
   "metadata": {},
   "source": [
    "- namely count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "704b3f2d-9cd9-4d42-8606-3b8a1eb920b7",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "new_numbers = (1, 2, 2, 2, 5, 5, 7, 9, 9, 10)\n",
    "new_numbers.count(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aeac69ac-fb62-417b-a642-142a7225e562",
   "metadata": {},
   "source": [
    "- index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51ceb740-27dd-4a62-8d63-51bb26e5530b",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "new_numbers = (1, 2, 2, 2, 5, 5, 7, 9, 9, 10)\n",
    "new_numbers.index(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ab7780b-b662-4747-84ae-f14e31b64464",
   "metadata": {},
   "source": [
    "## 9.**Dictionaries**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca355f7a-deb3-4ed1-9121-b5aa12fb37f1",
   "metadata": {},
   "source": [
    "- definition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2adf63c1-d0ae-47c8-8102-1dd8e05bfcbc",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "personal_details = {}\n",
    "personal_details[\"first name\"] = \"Rob\"\n",
    "personal_details[\"surname\"] = \"Mastrodomenico\"\n",
    "personal_details[\"gender\"] = \"Male\"\n",
    "personal_details[\"favourite_food\"] = \"Pizza\"\n",
    "personal_details"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f86f791-2e85-4ccc-9436-c5936112b830",
   "metadata": {},
   "source": [
    "or"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b9206cc-9b7c-4005-89dc-1fbd6a29708b",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "person_details = dict(first_name=\"Rob\", surname=\"Mastrodomenico\",gender=\"Male\", favourite_food=\"Pizza\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "452a35c7-b958-490b-a755-c3acbec94c2a",
   "metadata": {},
   "source": [
    "or"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57554176-57ff-480f-9f7a-4c4365ffda5e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "personal_details = {\"first name\": \"Rob\", \"surname\": \"Mastrodomenico\",\"gender\": \"Male\", \"favourite_food\": \"Pizza\"}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2085ad3f-9fd9-4f63-81f1-53a99fe30aec",
   "metadata": {},
   "source": [
    "or"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "156f2182-e685-470e-9aa5-1e6993915808",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "personal_details = dict([(\"first name\", \"Rob\"), (\"surname\", \"Mastrodomenico\"), (\"gender\", \"Male\"), (\"favourite_food\", \"Pizza\")])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f94b57a1-205a-413e-a564-41625d45fffc",
   "metadata": {},
   "source": [
    "or"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "930fa00d-5e96-47e4-8dd1-79ea09848a79",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "#using the fromkeys method.\n",
    "x = ('key1', 'key2', 'key3')\n",
    "y = 0\n",
    "res = dict.fromkeys(x, y)\n",
    "res"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d2d0fb3-a5c9-467f-ad63-4acc7e0cd9d9",
   "metadata": {},
   "source": [
    "- deal with it in a more sophisticated way: use a try except statement."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ec8dd900-242e-47bc-9622-997f2e18e2f1",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "personal_details = dict([(\"first name\", \"Rob\"), (\"surname\", \"Mastrodomenico\"),(\"gender\", \"Male\"), (\"favourite_food\", \"Pizza\")])\n",
    "personal_details\n",
    "try:\n",
    "\tage = personal_details[\"age\"]\n",
    "except KeyError:\n",
    "\tage = print('whoops~')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93ebd49e-af0f-48c8-9470-255784f2d3c8",
   "metadata": {},
   "source": [
    "- pop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f5090b54-9a77-4fac-8888-ca296b1d8ef8",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "personal_details\n",
    "personal_details.pop('gender')\n",
    "personal_details\n",
    "personal_details.popitem()\n",
    "personal_details"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df58479c-1b7d-4bd1-88f2-0c26b72b07a0",
   "metadata": {},
   "source": [
    "- del: we pass the dictionary name and key combination to remove that key value pair from the dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "167df1e3-6889-4fcf-ba46-f5dae5af2cfa",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "personal_details = dict([(\"first name\", \"Rob\"), (\"surname\", \"Mastrodomenico\"),(\"gender\", \"Male\"), (\"favourite_food\", \"Pizza\")])\n",
    "del personal_details['gender']\n",
    "personal_details"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7ced9c2-11b4-4e92-9d6f-6a682e477a7f",
   "metadata": {},
   "source": [
    "- Earlier we mentioned how if we assign one list to another the changes are reflected. The same is true for dictionaries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cad23095-8887-4172-b128-95904336078b",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "his_details = personal_details"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3109dc1-77ad-4064-9b84-6fa1e4bc713f",
   "metadata": {},
   "source": [
    "If we want to take a copy of a dictionary and independently make changes to it we can use the copy method in a similar way that we did with lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eb74405e-61fc-478c-b99f-04acc362cc8a",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "his_details = personal_details.copy()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ba786cd-ad07-4afb-98f0-5b6b5bbbac41",
   "metadata": {},
   "source": [
    "- clear out all contents of dictionary using the clear method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d03ddd68-c4fa-431f-a232-928435fc0eaf",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "personal_details.clear()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a0d71f1-7071-4df6-b73d-16c17be3937b",
   "metadata": {},
   "source": [
    "- access all keys and values from a `dictionary` using the following methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "366e2c40-0ab8-4443-b94e-8d660814350c",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "personal_details = dict([(\"first name\", \"Rob\"), (\"surname\", \"Mastrodomenico\"),(\"gender\", \"Male\"), (\"favourite_food\", \"Pizza\")])\n",
    "personal_details.items()\n",
    "personal_details.keys()\n",
    "personal_details.values()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "24d54a8d-b0ae-4824-ad79-a73c7e32c9f6",
   "metadata": {},
   "source": [
    "- The objects that we return can be iterated over and this is covered later when we introduce loops. However if you want to access them like we would a **list** we can cast them as such and access the relevant index positions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7208a482-e9d0-4c58-b726-81aec63e6616",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "list(personal_details.items())[0]\n",
    "list(personal_details.keys())[-1]\n",
    "list(personal_details.values())[:-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf149255-5865-4656-8ea5-339671342ae6",
   "metadata": {},
   "source": [
    "## 10.**Sets**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "118b4b1c-5de0-408c-ba1b-e1829a4438ef",
   "metadata": {},
   "source": [
    "They are also ***unordered*** and cannot be changed.\n",
    "\n",
    "Here, we can see that ***the ordering of the set doesn’t resemble*** what we put into it.\n",
    "\n",
    "Sets in Python are internally stored as `hash tables` to optimize the efficiency of lookups and duplicates removal, and this storage method **does not consider the order of the elements**. \n",
    "`Hash tables` use a `hash function` to compute a `hash value` for each element and store the elements in slots corresponding to their `hash values`. Since `hash values` are calculated by the `hash function`, they do not guarantee the order of the elements, thus the order of elements in a set is uncertain."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e2040f6-377f-43a6-b277-83d13255e021",
   "metadata": {},
   "source": [
    "- create"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5cb2a74a-6e75-4e0e-b32f-12c6004bd709",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "#use the curly brackets\n",
    "names = {'Tony','Peter','Natasha','Wanda', 1, 2, 3}\n",
    "names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07ced7bb-5dcd-412e-aa13-eee3e36742aa",
   "metadata": {},
   "source": [
    "or"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1329f354-933f-4370-a989-6b39f24a9bde",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "#use the set builtin function\n",
    "names = set(('Tony','Peter','Natasha','Wanda', 1, 2, 3))\n",
    "names\n",
    "names = set(['Tony','Peter','Natasha','Wanda', 1, 2, 3])\n",
    "names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a776407-2742-4a13-999e-9308ca35dc31",
   "metadata": {},
   "source": [
    "or"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f94735dc-0368-458a-952f-47c72a70f1b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "#pass in a string using the curly brackets you retain the full string in but when passed in using set the string is split into the individual characters. Again note when the characters are split there is no ordering to them.\n",
    "names = {'Wanda'}\n",
    "names\n",
    "names = set('Wanda')\n",
    "names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "004b32cc-5bc3-49c7-bbe6-02fc752a7e8e",
   "metadata": {},
   "source": [
    "- notice: add `dic`,` list`,` tuple` and `set` to the `set`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3862f19-4cd2-4288-b358-093dff8150f7",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "my_set = {'Tony','Wanda', 1, 2, (1,2,3)}\n",
    "my_set"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c3ed99c-d962-4a35-b33f-857861215bdf",
   "metadata": {},
   "source": [
    "The reason we can include the **tuple** over the `dictionary`,` list` and `set` is that the tuple cannot be changed so is supported in a set."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b2c5460-8a2e-441b-9b01-7f0e93106021",
   "metadata": {},
   "source": [
    "- We can see if the value is in the `set` by using the following syntax:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35848bc6-2089-43e2-949e-4f184efdd0f0",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "'Tony' in names\n",
    "'Steve' in names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "339601e0-88d9-482d-89d0-5a366e506842",
   "metadata": {},
   "source": [
    "- add"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "80c62972-83a0-4fe8-80f7-e77ef0b51ebf",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "names.add('Steve')\n",
    "names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcb272bc-8a28-4253-b20d-7ec97164f683",
   "metadata": {},
   "source": [
    "- That aspect of **not having duplicate values** within the set is useful if we want to have a unique representation of values where we could have duplicates. For example, you could imagine a long `list` with lots of repeated values and you just want the unique values within it as we show below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "05c5faa7-3c25-4574-90a5-b06dd8c72f16",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "days = ['Monday', 'Monday', 'Tuesday', 'Wednesday','Sunday', 'Sunday']\n",
    "days_set = set(days)\n",
    "days_set"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15e95273-3dc4-4173-b737-bf5d1c90984f",
   "metadata": {},
   "source": [
    "- operate on multiple sets, obtain the unique value between two sets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "774aecb8-60d9-4486-96df-20f28b4dd8b2",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "#use the | operator\n",
    "names = {'Tony','Peter','Natasha','Wanda'}\n",
    "more_names = {'Steve', 'Peter', 'Carol', 'Wanda'}\n",
    "names | more_names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ed475fb-aad3-41aa-afd1-dd5e9c368307",
   "metadata": {
    "tags": []
   },
   "source": [
    "achieve the same result as the list is converted into a set"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25ffbb0a-5822-49ad-9beb-65b9b44940d0",
   "metadata": {
    "tags": []
   },
   "source": [
    "- Now where we used union and the | operator if we want to find out what values are in all sets we use the `intersection` method or the `&` operator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0f66b3b7-fbac-4b54-8f18-14b83fdaab92",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "names = {'Tony','Peter','Natasha','Wanda'}\n",
    "more_names = {'Steve', 'Peter', 'Carol', 'Wanda'}\n",
    "names & more_names\n",
    "names.intersection(more_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90f558d4-094a-4aaf-b8db-d27c93bf5a68",
   "metadata": {},
   "source": [
    "we can add non-sets into the intersection method"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf313606-a5d3-4f54-877e-61e08937e0bd",
   "metadata": {},
   "source": [
    "- look at the differences between two or more sets, then we can use the `difference` method or the `−` operator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "07eaeafe-b762-490a-b598-559b9ce4f186",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "names - more_names\n",
    "names.difference(more_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1630077b-6b66-4a15-99f7-433f2973307a",
   "metadata": {},
   "source": [
    "The manner in which difference is applied for more than one comparison is to **work left to right** so we first look at the difference between names and more_names and then look at the difference between this result and even_more_names."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc092e39-71f1-48c1-a6c0-d9c859c30141",
   "metadata": {},
   "source": [
    "- use the symmetric_difference method or the `^` operator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2136a450-1f91-4bcd-b3bf-fdec4330fbb5",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "names ^ more_names\n",
    "names.symmetric_difference(more_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c14487c7-1dac-4d3e-81c0-bc2e0cf10a95",
   "metadata": {},
   "source": [
    "return back the elements that are **in either set but not in both**, so its like the or method but doesn’t include any common values."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "137fdfca-b950-4fe7-94a3-3de82dba608b",
   "metadata": {},
   "source": [
    "- isdisjoint method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "98a659eb-669d-4564-9dec-3dca3147c5d4",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "names.isdisjoint(more_names)\n",
    "more_names = {'Steve', 'Bruce', 'Carol', 'Sue'}\n",
    "names.isdisjoint(more_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8de4acd4-7852-4cde-a53b-b010ab619421",
   "metadata": {},
   "source": [
    "- issubset\n",
    "\n",
    "- issuperset\n",
    "\n",
    "- pop\n",
    "\n",
    "- remove\n",
    "\n",
    "- discard\n",
    "\n",
    "- clear\n",
    "\n",
    "- update"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8325442d-df67-4302-a4fd-bcbafe53839e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "names = {'Tony','Peter','Natasha','Wanda'}\n",
    "more_names = {'Steve', 'Peter', 'Carol', 'Wanda'}\n",
    "names | more_names\n",
    "names\n",
    "more_names\n",
    "names.update(more_names)\n",
    "names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61ed435e-7899-44c2-a7b6-6be5fc4e23d9",
   "metadata": {},
   "source": [
    "The big difference here is that when you use the `|` operator you don’t change either of the sets, however using the `update` method changes the set that you have used the method for so in this case the `names` set is now the result of `names` `|` `more_names`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09dae136-30ce-4a4a-95b4-fef5d8b27e13",
   "metadata": {},
   "source": [
    "- frozen set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8434f47f-a67e-4036-aff3-e58a1c6ea3f4",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "frozen_names = frozenset({'Tony','Peter','Natasha','Wanda'})\n",
    "frozen_names\n",
    "frozen_names = frozenset(['Tony','Peter','Natasha','Wanda'])\n",
    "frozen_names\n",
    "frozen_names = frozenset(('Tony','Peter','Natasha','Wanda'))\n",
    "frozen_names\n",
    "frozen_names = frozenset('Tony')\n",
    "frozen_names"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1865499e-998a-4182-885f-5a90703f267f",
   "metadata": {},
   "source": [
    "The frozen set is what the tuple is to a list in that it cannot be altered"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d4af75b3-ffd9-4514-903e-bf978ecfd418",
   "metadata": {},
   "source": [
    "## 11.**Loops, if, Else, and While**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f3ba73e-770c-448a-8515-896092c4fb29",
   "metadata": {},
   "source": [
    "- if\n",
    "\n",
    "- else\n",
    "\n",
    "- elif\n",
    "\n",
    "- list\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d211b99d-426d-4870-9f1b-8a75f2a11d87",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "people=[[\"Tony\", \"Stark\", 48], [\"Steve\", \"Rodgers\", 102],[\"Stephen\", \"Strange\", 42],[\"Natasha\", \"Romanof\", 36], [\"Peter\", \"Parker\", 16]]\n",
    "people[0][2]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3402342e-5084-4fdd-8b14-df0463c1234f",
   "metadata": {},
   "source": [
    "- for in\n",
    "\n",
    "- while"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fa18727-c9ed-455f-a532-05bc1a3469b0",
   "metadata": {},
   "source": [
    "## 12.**Strings**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a614eb3-5fef-46fa-86fe-b0614ae51d69",
   "metadata": {},
   "source": [
    "- use an `escape sequence`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a48fc8c-61a8-4104-809c-5f980ffc8ff2",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "single_quote_string = 'string with a \\' single quote'\n",
    "single_quote_string"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "708d50da-155e-4e58-90a2-449ff87d44a3",
   "metadata": {},
   "source": [
    "We can get away with not using `escape sequences` if we use triple quotes. So we can rewrite the previous using `triple quotes` as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "870e29e9-2c22-406c-af63-a42787492f3d",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "single_quote_string = \"\"\"string with a ' single quote\"\"\"\n",
    "single_quote_string"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "570640c3-c37c-4bff-87a2-451dc5c1019e",
   "metadata": {},
   "source": [
    "- typing `backslash n` gives us a carriage return in our string. But what if we want forward `slash n` in our string, we can use what is called a `raw string`:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e0294a1d-cf60-43e2-97ff-998010951f7d",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "raw_string = \"This has a \\n in it\" \n",
    "raw_string\n",
    "print(raw_string)\n",
    "\n",
    "raw_string = r\"This has a \\n in it\" \n",
    "raw_string\n",
    "print(raw_string)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9076134d-8203-4d41-a326-e9f249460ab6",
   "metadata": {},
   "source": [
    "In both examples when we show the content of the string it has an extra forward slash but when it is printed this disappears. And yes if you wanted an extra slash in there just use three slashes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6786af15-dc79-4fa5-be4b-0144a9aebe84",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "not_raw_string = \"This has a \\\\\\n in it\" \n",
    "not_raw_string\n",
    "print(not_raw_string)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0da14d44-b1e2-4a11-b495-00c0d1ca34b7",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "'''In Python, the backslash (\\) is an escape character used to escape special characters. Some of the special characters that can be escaped using the backslash include:\n",
    "\n",
    "\\n: Newline character (Line Feed)\n",
    "\n",
    "\\t: Horizontal Tab\n",
    "\n",
    "\\b: Backspace\n",
    "\n",
    "\\r: Carriage Return\n",
    "\n",
    "\\f: Form Feed\n",
    "\n",
    "\\v: Vertical Tab\n",
    "\n",
    "\\\\: Backslash itself\n",
    "\n",
    "\\\": Double quote\n",
    "\n",
    "\\': Single quote\n",
    "\n",
    "\\a: Bell character (Alert)\n",
    "\n",
    "\\e: Escape character (Escape)\n",
    "\n",
    "\\xHH: Hexadecimal escape, where HH is a two-digit hexadecimal number\n",
    "\n",
    "\\ooo: Octal escape, where ooo is a three-digit octal number'''"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0916b84d-794b-4a6b-b266-fd09a51a4742",
   "metadata": {},
   "source": [
    "- select element\n",
    "\n",
    "- boolean\n",
    "\n",
    "- put a variable into our string we need only define the position in the string using curly brackets and then using the format method with the arguments passed in they get assigned to the appropriate positions.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "baa43a86-840c-4cc6-aaab-57f76165cd00",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "first_name = \"Rob\"\n",
    "last_name = \"Mastrodomenico\"\n",
    "name = \"First name: {}, Last name: {}\".format(first_name, last_name)\n",
    "name"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94ad5d69-a29e-4b2f-9d42-001806da8a33",
   "metadata": {},
   "source": [
    "We can also give the positions in the curly brackets to where we want the variables assigned, so we could write the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6c5fa67-509b-4f8c-a89a-e68b98585035",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "first_name = \"Rob\"\n",
    "last_name = \"Mastrodomenico\"\n",
    "name = \"First name: {1}, Last name: {0}\".format(first_name, last_name) \n",
    "name"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2bae6599-2dc0-46fe-889f-8a8cd8a6ddde",
   "metadata": {},
   "source": [
    "That is wrong but you get the point. We can also define each value as a variable and pass that variable name in the curly brackets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "318670ff-cf0f-4a72-9dbb-4e7ecf6b9726",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "first_name = \"Rob\"\n",
    "last_name = \"Mastrodomenico\"\n",
    "name = \"First name: {f}, Last name: {l}\".format(f=first_name, l=last_name)\n",
    "name"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbd2e473-c175-48b5-9231-73ad51d00689",
   "metadata": {},
   "source": [
    "- convert a string to all uppercase letters and then all lowercase letters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8020b65d-d5bf-49aa-b26d-67c36dc0778d",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "name.lower()\n",
    "name.lower()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65a9def4-3780-464d-9618-866864eab027",
   "metadata": {
    "tags": []
   },
   "source": [
    "- split up strings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c3d5e62-2b26-429b-adc4-36898aa79ec8",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "name = \"Rob Mastrodomenico\"\n",
    "name.split(\" \")\n",
    "first_name, last_name = name.split(\" \")\n",
    "first_name\n",
    "last_name"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6e58fcf-1478-45b3-bc15-08cf362f9e3b",
   "metadata": {},
   "source": [
    "- a comma separated string which you may find in a `csv file` can be split into the variables it contains"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eb30d5f8-f7da-4a2d-882e-a7dcced01a09",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "match_details = \"Manchester United,Arsenal,2,0\"\n",
    "match_details\n",
    "match_details.split(\",\")\n",
    "home_team, away_team = match_details.split(\",\")[0:2]\n",
    "home_team\n",
    "away_team\n",
    "home_goals, away_goals = match_details.split(\",\")[2:4]\n",
    "home_goals\n",
    "away_goals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f86a4875-fe76-44c1-804a-6a0159f4e00c",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "#replace all the commas with colons\n",
    "match_details = \"Manchester United,Arsenal,2,0\"\n",
    "match_details\n",
    "match_details.replace(\",\",\":\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22a27b4e-635a-425a-84f4-4d44fea97b86",
   "metadata": {},
   "source": [
    "- apply the **join method** on the string containing just the `comma` and it then creates `a string of the values` in the `list` separated by the string that we applied the method on. \n",
    "\n",
    "  This is a very useful method when it comes to **creating strings from lists separated by a common value**.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7c48db68-e08c-43b6-9826-602bf7bf926f",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "details = ['Manchester United', 'Arsenal', '2', '0']\n",
    "match_details = ','.join(details)\n",
    "match_details"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "735325c0-5300-4947-9360-76bfd2a4783b",
   "metadata": {},
   "source": [
    "- len"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ce9c555-f32b-4284-b4b5-02edc3452a3c",
   "metadata": {},
   "source": [
    "## 13.**Regular Expressions**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0fd6a3fb-e3bb-4310-aeb1-d2bf300fa4ea",
   "metadata": {},
   "source": [
    "- package re\n",
    "\n",
    "- finding all the characters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f0691fa-11b1-4072-8ed3-3c00d224c588",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import re\n",
    "name = 'Rob Mastrodomenico'\n",
    "x = re.findall(\"[a-m]\", name)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "254819c8-13f9-452b-8680-5bf47a8d83f4",
   "metadata": {},
   "source": [
    "- find the integer values 0–9 within a sequence "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dfb0efd7-6fc9-48ff-b1b6-e54347b44a12",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = 'Find all numerical values like 1, 2, 3' \n",
    "x = re.findall(\"\\d\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41c9b180-cef0-43bf-a80d-27b3d88d7a86",
   "metadata": {},
   "source": [
    "In regular expressions, `\\d` is a very common character class used to match any single digit character. However, there are other related usages and combinations that can be used to match different types of numeric sequences:\n",
    "1. `\\d+`: Matches one or more consecutive digits. For example, in the string \"123abc\", `\\d+` will match \"123\".\n",
    "2. `\\d*`: Matches zero or more consecutive digits. For example, in the string \"abc\", `\\d*` will match an empty string (because there are no digits).\n",
    "3. `\\d?`: Matches zero or one digit. For example, in the string \"a1b2c3\", `\\d?` will match \"1\", \"2\", and \"3\" separately.\n",
    "4. `\\d{3}`: Matches exactly three consecutive digits. For example, in the string \"123abc456\", `\\d{3}` will match \"123\" and \"456\".\n",
    "5. `\\d{2,4}`: Matches at least two but no more than four consecutive digits. For example, in the string \"1234abc5678\", `\\d{2,4}` will match \"1234\" and \"5678\".\n",
    "6. `^\\d`: Matches a digit at the beginning of a string. For example, in the string \"1abc\", `^\\d` will match \"1\".\n",
    "7. `\\d$`: Matches a digit at the end of a string. For example, in the string \"abc1\", `\\d$` will match \"1\".\n",
    "8. `[\\d]`: Using `\\d` within a character set, it matches any single digit. This is the same as using `\\d` by itself.\n",
    "9. `[^.\\d]`: Using `\\d` in a negated character set, it matches any single character that is not a digit. For example, in the string \"a1b2c3\", `[^.\\d]` will match \"a\", \"b\", and \"c\".\n",
    "10. `(\\d+)`: Uses parentheses to create a capture group that matches and captures one or more consecutive digits. For example, in the string \"123abc456\", `(\\d+)` will match \"123\" and \"456\", and these matched numbers can be processed as capture groups后续处理.\n",
    "These usages can be combined and nested as needed to build more complex regular expressions, thus matching specific numeric patterns or extracting the required information.\n",
    "\n",
    "use re.findall()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64c4f08a-faa7-4999-8ca1-93d7f01e1285",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = re.findall(\"[0-9]\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e32c778d-a8cf-4712-8fd6-0baeca2ff2c8",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = 'Find all numerical values like 1, 2, 3, 3'\n",
    "x = re.findall(\"[0-9]\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "54ed7510-4132-4fc8-910d-b7074f6ef446",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = re.findall(\"\\d\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9aabbaa4-212e-4321-aff0-7b9740a931c1",
   "metadata": {},
   "source": [
    "-  look for specific patterns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a34a21be-ae81-43c5-ba3b-7a6fd4f05282",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = \"hello world\"\n",
    "x = re.findall(\"he..o\", txt)\n",
    "x\n",
    "txt = \"hello helpo hesoo\" \n",
    "x = re.findall(\"he..o\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b1df4c7-251b-4b2a-81cb-8b7127665101",
   "metadata": {},
   "source": [
    "-  search specifically on the start of the string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "351bf98d-2dbb-4913-8feb-038a3d311594",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt ='starts at the end'\n",
    "x = re.findall(\"^start\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "955f1488-271e-4c83-a37d-234ffccd1824",
   "metadata": {},
   "source": [
    "-  look at the last word in the string by using ending the searched string with the $ sign"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0073cc3c-4f44-4251-b1d3-798e135b9a6e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = 'the last word is end'\n",
    "x = re.findall(\"end$\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "513fb205-d859-4aee-80b0-9145ae3c0143",
   "metadata": {},
   "source": [
    "-  find the occurrences of ai followed by 0 or more x values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8be1cac3-c732-4224-a196-99ea4bf6a52a",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = \"The rain in Spain falls mainly in the plain!\" \n",
    "x = re.findall(\"aix*\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f4b581c-0954-4ba0-98cc-9569cc8a9e48",
   "metadata": {},
   "source": [
    "-  Expanding on the previous example you can find the number of instances of the string ai followed by one or more x by adding the + symbol. Applying that to the same string as before gives us the result of an empty string as we don’t have aix within it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0928ecae-fb82-4164-aae3-81de85454204",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = \"The rain in Spain falls mainly in the plain!\" \n",
    "x = re.findall(\"aix+\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1112fe65-0cb6-4034-9214-0cb7e688ab20",
   "metadata": {},
   "source": [
    "-  a specified number of characters, use curly brackets containing the number of instances we are interested in"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2dee6bd0-3983-4dc3-942f-67ead1b6b103",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = 'The cow said moo'\n",
    "x = re.findall(\"mo{2}\", txt)\n",
    "x\n",
    "x = re.findall(\"moo\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38864ac8-7617-4755-ae60-9c248432d6f7",
   "metadata": {},
   "source": [
    "-  use the | symbol between the two strings, to find one or another value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fd426146-83b9-430e-92fe-08a5e336b986",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = \"The Avengers are earths mightiest heroes go Avengers\" \n",
    "x = re.findall(\"Avengers|heroes\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ece3b7d1-01c3-456f-995b-f1a602abe0b8",
   "metadata": {},
   "source": [
    "-  use special sequences (returns the whitespace)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fcc15c3b-ccb2-4b00-b6f2-feb808df8878",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = \"Is there whitespace\"\n",
    "x = re.findall(\"\\s\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3c265e4-2c2d-49a4-b3ad-562da8c41655",
   "metadata": {},
   "source": [
    "-  There are other special sequences that we can use, they are listed as follows:\n",
    "    \n",
    "    \\A: This matches if the characters defined are at the beginning of the string \"\\AIt\"\n",
    "    \n",
    "    \\b: This matches if the characters defined are at the beginning or at the end of a word \"\\bain\" r\"ain\\b\"\n",
    "    \n",
    "    \\B Returns a match where the specified characters are present, but NOT at the beginning (or at the end) of a word (the \"r\" in the beginning is making sure that the string is being treated as a \"raw string\") r\"\\Bain\" r\"ain\\B\"\n",
    "    \n",
    "    \\d Returns a match where the string contains digits (numbers from 0-9) \"\\d\"\n",
    "    \n",
    "    \\D Returns a match where the string DOES NOT contain digits \"\\D\"\n",
    "    \n",
    "    \\s Returns a match where the string contains a white space character \"\\s\"\n",
    "    \n",
    "    \\S Returns a match where the string DOES NOT contain a white space character \"\\S\"\n",
    "    \n",
    "    \\w Returns a match where the string contains any word characters (characters from a to Z, digits from 0-9, and the underscore _ character) \"\\w\"\n",
    "    \n",
    "    \\W Returns a match where the string DOES NOT contain any word characters \"\\W\"\n",
    "    \n",
    "    \\Z Returns a match if the specified characters are at the end of the string\n",
    "\n",
    "\n",
    "-  split method\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1020d60d-841e-4dfd-a94f-8543057bb09a",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = re.split(\"\\s\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c603400-1959-483d-ac58-4205348ac5b5",
   "metadata": {},
   "source": [
    "-  specify the number of times we want the split to be done by using the maxsplit argument"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "62a25caa-ee65-4155-953a-3f1266422aea",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = re.split(\"\\s\", txt, maxsplit=1)\n",
    "x\n",
    "x = re.split(\"\\s\", txt, maxsplit=2)\n",
    "x\n",
    "x = re.split(\"\\s\", txt, maxsplit=3)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa1b4d60-39bc-4961-b369-4037009c9677",
   "metadata": {},
   "source": [
    "-  replace on a string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be28d537-7e6e-4101-b489-4ba0cfe063b1",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = re.sub(\"\\s\", \"9\", txt)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c4d79ff-da9a-4ba7-86b5-44d5b6b2cf28",
   "metadata": {},
   "source": [
    "-  combine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "573de731-b51e-438e-b6c7-bc003c9ab6f4",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "x = re.sub(\"\\s\", \"9\", txt, 1)\n",
    "x\n",
    "x = re.sub(\"\\s\", \"9\", txt, 2)\n",
    "x\n",
    "x = re.sub(\"\\s\", \"9\", txt, 3)\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc866b25-b47e-4ece-afc9-f4bc2fdcbc2e",
   "metadata": {},
   "source": [
    "-  span"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b3fbf36c-e7c2-45ae-93c8-6324e57f969c",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "txt = \"The rain in Spain falls mainly in the plain!\" \n",
    "x = re.search(\"ai\", txt)\n",
    "x.span()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0520ddf-3ee0-4892-a326-5af88a44324b",
   "metadata": {},
   "source": [
    "more reference of reg-expression\n",
    "\n",
    "https://www.runoob.com/python/python-reg-expressions.html"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe23694b-3379-46e8-ad91-0b05874335d1",
   "metadata": {},
   "source": [
    "## 14.**Dealing with Files**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a3f1ff7-474f-4323-9571-e6c5751d0ba9",
   "metadata": {},
   "source": [
    "## 15.**Functions and Classes**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "876685ee-b42c-47de-ad7a-3e2a0e09248e",
   "metadata": {},
   "source": [
    "- define a function called lottery: use the command def followed by the name that you want to give the function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c2a7d8c-b0d8-4bb5-a0ab-2ed8cc86166e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def lottery(min, max):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f917751-2a3f-4e2e-ad28-1d09642da58c",
   "metadata": {},
   "source": [
    "- Classes: can be very powerful objects which allow us to bundle together lots of functions and variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d710701d-b9a4-497c-b8c7-c3d50e04e846",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "class MyClass:\n",
    "    x = 10\n",
    "mc = MyClass()\n",
    "mc.x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1118c98e-5cfc-4b12-823b-6ed87e708d8e",
   "metadata": {},
   "source": [
    "- create an init method using `__init__` this initialiser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "055c2c1e-0c3d-4b71-932f-b80bf7c43520",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "class Lottery:\n",
    "    def __init__(self, min=1, max=59, draw_length=7):\n",
    "        self.min = min\n",
    "        self.max = max\n",
    "        self.draw_length = draw_length\n",
    "    def lottery(self):\n",
    "        pass #codes"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cad32412-286a-4e73-b06b-991cee450082",
   "metadata": {},
   "source": [
    "- in this code, we define the class in the way we did before and call it Lottery. Next, we create an init method using `__init__` this initialiser is called when we define the class so we can pass in arguments from here that can be used within the class. Note that we can use the standard defaults but these are then assigned to the class by using the self-dot syntax which allows that value to be part of class and then allowed to be used anywhere within the class. We can create the class in the following example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "547f7333-5347-4d80-a9ec-7fa6b78e892a",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "l = Lottery()\n",
    "l.lottery()\n",
    "l = Lottery(1,49,6)\n",
    "l.lottery()\n",
    "l = Lottery(draw_length=8)\n",
    "l.lottery()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42d44c73-4a68-4387-86b4-be293e2f8a3a",
   "metadata": {},
   "source": [
    "- import the package sys and look at the sys.path list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7d6994a3-1c99-47f4-a85d-985b3fad2dba",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08f6821c-bb30-4bcb-900e-abecaa22805f",
   "metadata": {},
   "source": [
    "import the contents of the lottery.py file.\n",
    "\n",
    "  If we create a file called import_lottery.py in the same directory as the lottery.py we can run the Lottery class as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1cfc772d-55f1-470b-a095-b0eb2b73bf24",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from lottery import *"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b47d394-7943-4c50-bb99-4f75c1d94625",
   "metadata": {},
   "source": [
    "**notice**\n",
    "\n",
    "1. `import lottery`: This import method loads the entire `lottery` module, but you need to use the `lottery.` prefix to access functions, classes, or variables within the module. For example:\n",
    "   ```python\n",
    "   import lottery\n",
    "   lottery.draw_lottery()\n",
    "   ```\n",
    "   In this case, you must refer to the `draw_lottery` function with the `lottery.` prefix.\n",
    "   \n",
    "2. `from lottery import *`: This import method imports all available functions, classes, and variables from the `lottery` module without needing to use the module name as a prefix. This means you can directly call `draw_lottery()` without the `lottery.` prefix. For example:\n",
    "   ```python\n",
    "   from lottery import *\n",
    "   draw_lottery()\n",
    "   ```\n",
    "   In this case, you can directly use `draw_lottery()`, as it has been directly imported into the current namespace.\n",
    "   \n",
    "However, using `from lottery import *` is not recommended because it imports all names from the module, which can lead to name conflicts, especially when the module contains many names. \n",
    "\n",
    "Additionally, this import method can also make the code less readable, as readers may not be clear about which module certain functions or classes are imported from.\n",
    "\n",
    "Therefore, unless you are very sure that all names in the `lottery` module will not conflict with other names in your code, it is better to use `import lottery` and use the `lottery.` prefix to clearly indicate the module from which functions, classes, or variables are coming. This approach can avoid potential naming conflicts and improve code readability."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8cc361f3-177f-4298-a241-8d96a5667d0d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
